package com.voodoo.lib_mqtt;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;

import androidx.annotation.Nullable;

import com.voodoo.lib_logcat.L;
import com.voodoo.lib_mqtt.listener.MqttConnectionListener;
import com.voodoo.lib_mqtt.listener.MqttCallbackListener;
import com.voodoo.lib_utils.ServiceUtils;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Author：voodoo
 * CreateTime：2021/06/17 017 上午 09:33
 * Description：Mqtt 服务，本类不要修改
 */
public class MqttService extends Service {

    @SuppressLint("StaticFieldLeak")
    public static volatile MqttAndroidClient mqttClient;
    public MqttConnectOptions mqttConnectOptions;

    Timer timer;
    TimerTask timerTask;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        L.i("Mqtt服务启动，启动Mqtt守护服务");
        startService(new Intent(this, MqttGuardService.class));

        initMqtt(MqttConstant.BASE_URL, MqttConstant.CLIENT_ID, 60, 60);

    }

    /**
     * 初始化Mqtt配置
     *
     * @param urlStr         链接地址
     * @param clientId       id
     * @param connectTimeOut 链接超时，单位秒
     * @param heartbeatTime  心跳间隔
     */
    private void initMqtt(String urlStr, String clientId, int connectTimeOut, int heartbeatTime) {

        if (mqttClient != null) {
            try {
                mqttClient.disconnect();
                mqttClient.close();
                mqttClient = null;
            } catch (MqttException e) {
                L.e("Mqtt断开异常");
            }
        }
        mqttClient = new MqttAndroidClient(getApplicationContext(), urlStr, clientId);
        mqttClient.setCallback(new MqttCallbackListener()); // 设置MQTT监听并且接收消息

        if (mqttConnectOptions != null) {
            mqttConnectOptions = null;
        }
        mqttConnectOptions = new MqttConnectOptions(); // 设置MQTT 配置类
        mqttConnectOptions.setConnectionTimeout(connectTimeOut); // 连接超时 单位：秒
        mqttConnectOptions.setKeepAliveInterval(heartbeatTime); // 心跳包发送间隔，单位：秒
        mqttConnectOptions.setCleanSession(true); // 客户端和服务器是否记录重启和重连的状态。

        try {
            // Signature 方式 参考 https://help.aliyun.com/document_detail/54225.html
            // mqttConnectOptions.setUserName("Signature|" + Constant.Mqtt.ACCESS_KEY + "|" + Constant.Mqtt.INSTANCE_ID);
            // mqttConnectOptions.setPassword(AliTool.macSignature(Constant.Mqtt.CLIENT_ID, Constant.Mqtt.SECRET_KEY).toCharArray());

            mqttConnectOptions.setUserName(MqttConstant.USER_NAME);
            mqttConnectOptions.setPassword(MqttConstant.PASS_WORD.toCharArray());
            mqttConnectOptions.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
        } catch (Exception e) {
            L.e("Mqtt设置用户名和密码错误", e.toString());
        }

        startConnectTimer();

    }

    /**
     * 开始计时轮询链接状态
     */
    public void startConnectTimer() {
        cancelConnectTimer();
        timer = new Timer();
        timerTask = new TimerTask() {
            @Override
            public void run() {
                checkedMqttGuardServicesLife();
                doClientConnection();
            }
        };
        // 启动后两秒钟检查一次链接，之后每一分钟检查一次
        timer.schedule(timerTask, 2_000, 60_000);
    }

    /**
     * 取消计时查询链接状态
     */
    public void cancelConnectTimer() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if (timerTask != null) {
            timerTask.cancel();
            timerTask = null;
        }
    }

    /**
     * 检查并链接 Mqtt
     */
    public void doClientConnection() {
        L.i("Mqtt" + (!mqttClient.isConnected() ? "不在线，尝试连接" : "在线"));
        if (!mqttClient.isConnected()) {
            if (isConnectIsNomarl()) {
                try {
                    // 此处连接成功之后回调中开始订阅主题
                    mqttClient.connect(mqttConnectOptions, null, new MqttConnectionListener(mqttClient));
                } catch (MqttException e) {
                    L.e("链接Mqtt服务器异常", e.toString());
                    e.printStackTrace();
                }
            } else {
                L.e("当前网络不可用");
            }
        }
    }

    /**
     * 检查 Mqtt守护进程服务是否活着
     */
    private void checkedMqttGuardServicesLife() {
        boolean mqttGuardServiceRunning = ServiceUtils.isServiceRunning(getApplicationContext(), MqttGuardService.class.getName());
        L.i("Mqtt服务：Mqtt守护进程" + (!mqttGuardServiceRunning ? "挂了" : "活着")); // 之所以反着来判断是为了直观的知道下面这部判断
        if (!mqttGuardServiceRunning) {
            L.i("Mqtt服务：重新启动Mqtt守护进程");
            ServiceUtils.startService(getApplicationContext(), MqttGuardService.class);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        String intentExtraValue = intent.getStringExtra(MqttConstant.INTENT_EXTRA_PARAM_KEY);
//        if (MqttConstant.SEND_MESSAGE.equals(intentExtraValue)) {
//            // 发送消息的接口
//            String topic = intent.getStringExtra(MqttConstant.SEND_MSG_TOPIC_KEY);
//            String msg = intent.getStringExtra(MqttConstant.SEND_MSG_MESSAGE_KEY);
//
//            L.i(String.format("执行发送Mqtt的方法：\ntopic=%s\nsendMsg=%s", topic, msg));
//            if (topic == null || msg == null || topic.isEmpty() || msg.isEmpty()) {
//                L.e("topic和message均不能为空");
//            } else {
//                sendMessage(topic, msg);
//            }
//        }
        return super.onStartCommand(intent, flags, startId);
    }

    public static void sendMessage(final String topic, final String msg) {
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                MqttMessage message = new MqttMessage();
                message.setPayload(msg.getBytes());
                mqttClient.publish(topic, message, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        L.i(String.format("Mqtt消息发送成功\ntopic=%s\nmsg=%s", topic, msg));
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        L.e(String.format("Mqtt消息发送失败\ntopic=%s\nmsg=%s\nexception=%s", topic, msg, exception.toString()));
                    }
                });
            } else {
                L.e(String.format("Mqtt发送消息异常\ntopic=%s\nmsg=%s\nexception=%s", topic, msg, "mqtt 不在线"));
            }
        } catch (MqttException exception) {
            L.e(String.format("Mqtt发送消息异常\ntopic=%s\nmsg=%s\nexception=%s", topic, msg, exception.toString()));
        }
    }

    /**
     * 判断网络是否连接
     */
    private boolean isConnectIsNomarl() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();
        if (info != null && info.isConnected()) {
//            String name = info.getTypeName();
            L.e("MQTT当前网络可用");
            return true;
        } else {
            L.e("MQTT当前网络不可用");
            return false;
        }
    }


    public static boolean isConnected() {
        if (mqttClient != null) {
            return mqttClient.isConnected();
        }
        return false;
    }
}
